/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewJPanel.java
 *
 * Created on 01-Apr-2009, 16:59:18
 */

package edu.napier.soc.xfdm.uci;

import edu.napier.soc.xfdm.model.Constraint;
import edu.napier.soc.xfdm.model.EntityFunction;
import edu.napier.soc.xfdm.model.EntityType;
import edu.napier.soc.xfdm.model.Function;
import edu.napier.soc.xfdm.model.ReturnType;
import java.awt.BorderLayout;
import java.awt.Color;

import java.awt.Dimension;
import java.util.LinkedList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.SwingConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

/**
 *
 * @author Thomas
 */
public class EntityTypeView extends javax.swing.JPanel {

	private EntityType entityType;
	private List<RelationshipModel> relationships;

    /** Creates new form NewJPanel */
    public EntityTypeView(EntityType entityType) {
        initComponents();
		this.relationships = new LinkedList<RelationshipModel>();
		this.entityType = entityType;
		label.setText(entityType.getName());
		setTree(entityType.getFunctions(),
				entityType.getConstraints());
		int height = tree.getPreferredSize().height + 20;
		int width = tree.getPreferredSize().width + 20;
		setPreferredSize(new Dimension(width, height));
    }



    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        label = new JLabel();
        tree = new JTree();

        setLayout(new BorderLayout());

        label.setHorizontalAlignment(SwingConstants.CENTER);
        add(label, BorderLayout.PAGE_START);

        tree.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
        tree.setRootVisible(false);
        tree.setSelectionModel(null);
        add(tree, BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

	public void setTree(List<Function> functions,
			List<Constraint> constraints) {
		DefaultMutableTreeNode treeNode1 =
				new DefaultMutableTreeNode("EntityType");
		DefaultMutableTreeNode treeNode2 =
				new DefaultMutableTreeNode("Functions");
		DefaultMutableTreeNode treeNode3 =
				new DefaultMutableTreeNode("Constraints");

		for (Function f : functions) {
			if (entityType.isSupertypeFunction(f)) {
				continue;
			}
			ReturnType r = f.getReturnType();

			if (r == ReturnType.ENTITY) {
				relationships.add(RelationshipModel.newInstance(f));
				continue;
			}
			String s = f.getName() + " - " + f.getReturnType();
			DefaultMutableTreeNode tn = new DefaultMutableTreeNode(s);
			treeNode2.add(tn);
		}

		EntityType supertype = entityType.getSupertype();
		if (supertype != null) {
			relationships.add(RelationshipModel.newSupertypeModel(supertype));
		}

		for (Constraint c : constraints) {
			String s = c.getName() + " - " + c.getConstraintType();
			DefaultMutableTreeNode tn = new DefaultMutableTreeNode(s);
			treeNode3.add(tn);
		}

		treeNode1.add(treeNode2);
		treeNode1.add(treeNode3);

		tree.setModel(new DefaultTreeModel(treeNode1));

		for (int i = 0; i < tree.getRowCount(); i++) {
			tree.expandRow(i);
		}
	}

	public EntityType getEntityType() {
		return entityType;
	}

	public List<RelationshipModel> getRelationships() {
		return relationships;
	}
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JLabel label;
    private JTree tree;
    // End of variables declaration//GEN-END:variables

	public static class RelationshipModel {

		public enum Cardinality {
			ONETOONE("1:1"), ONETOMANY("1:N"), SUPERTYPE("inherits");
			private final String name;

			Cardinality(String name) {
				this.name = name;
			}

			public String getName() {
				return name;
			}
		}

		private final EntityType e;
		private final Cardinality c;
		private final Function f;

		private RelationshipModel(Function f, EntityType e, Cardinality c) {
			this.e = e;
			this.c = c;
			this.f = f;
		}

		public static RelationshipModel newSupertypeModel(
				EntityType supertype) {
			return new RelationshipModel(null, supertype,
					Cardinality.SUPERTYPE);
		}

		public static RelationshipModel newInstance(Function f) {
			Cardinality c = f.isMultiValued()
					? Cardinality.ONETOMANY : Cardinality.ONETOONE;
			return new RelationshipModel(f, ((EntityFunction)f).getEntityType(), c);
		}

		public EntityType getRelationshipTo() {
			return e;
		}

		public Cardinality getCardinality() {
			return c;
		}

		public Function getFunction() {
			return f;
		}
	}
}
